package org.jeecg.modules.common.utils;


import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;


import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 实体对象批量处理类
 */
public class EntityBatchOperate <M extends BaseMapper<T>, T>  {

    protected Log log = LogFactory.getLog(getClass());

    @Autowired
    protected M baseMapper;


    public M getBaseMapper() {
        return baseMapper;
    }

    protected Class<T> entityClass = currentModelClass();


    public Class<T> getEntityClass() {
        return entityClass;
    }

    protected Class<M> mapperClass = currentMapperClass();

    /**
     * 判断数据库操作是否成功
     *
     * @param result 数据库操作返回影响条数
     * @return boolean
     * @deprecated 3.3.1
     */
    @Deprecated
    protected boolean retBool(Integer result) {
        return SqlHelper.retBool(result);
    }

    protected Class<M> currentMapperClass() {
        return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 0);
    }

    protected Class<T> currentModelClass() {
        return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 1);
    }

    @Autowired
    public BeanObjUtil beanObjUtil;


    /**
     * 根据ids和一个对象，批量更新复制属性给ids对应的数据
     * @param ids
     * @param entityObj
     * @return
     */
    public UpdateWrapper batchCopyUpdate(String[] ids, T entityObj ) {

        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", ids); // 设置需要更新的字段
        return batchCopyUpdate(updateWrapper,entityObj,null);
    }
    /**
     * 根据ids和一个对象，批量更新复制属性给ids对应的数据
     * @param ids
     * @param entityObj
     * @return
     */
    public UpdateWrapper batchCopyUpdate(List ids, T entityObj ) {

        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", ids); // 设置需要更新的字段
        return batchCopyUpdate(updateWrapper,entityObj,null);
    }
    public UpdateWrapper batchCopyUpdate(UpdateWrapper<T> updateWrapper, T setEntityObj , T whereEntityObj ){
        List<Field> setfieldlist = oConvertUtils.isNotEmpty( setEntityObj) ? beanObjUtil.getAllField(setEntityObj.getClass()) : null;

        for (  Field fieldOne : setfieldlist
        ) {
            String fieldName = fieldOne.getName();
            Object fieldValue = beanObjUtil.getFieldValueByName(setEntityObj,fieldName);
            //动态获取表名对应的属性列名
            String columnName = getColumnNameByField(fieldOne);
            if(oConvertUtils.isNotEmpty( fieldValue)  ){
                updateWrapper.set(columnName,fieldValue);
            }
        }

        List<Field> wherefieldlist = oConvertUtils.isNotEmpty( whereEntityObj) ? beanObjUtil.getAllField(whereEntityObj.getClass()) : null;

        for (  Field fieldOne : wherefieldlist
        ) {
            String fieldName = fieldOne.getName();
            Object fieldValue = beanObjUtil.getFieldValueByName(setEntityObj,fieldName);
            //动态获取表名对应的属性列名
            String columnName = getColumnNameByField(fieldOne);
            if(oConvertUtils.isNotEmpty( fieldValue)  ){
                updateWrapper.eq(columnName,fieldValue);
            }
        }

        return updateWrapper;

    }

    public UpdateWrapper batchCopyUpdate(Map<String,Object> whereCondition, T entityObj ){

        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        for (String keyFieldName : whereCondition.keySet()
             ) {
            Object conditionValue = whereCondition.get(keyFieldName);
            //动态获取表名对应的属性列名
            String columnName = getColumnNameByFieldName(entityObj.getClass(),keyFieldName);

            if(oConvertUtils.isNotEmpty( columnName) && oConvertUtils.isNotEmpty( conditionValue) ) {
                if (conditionValue instanceof List && oConvertUtils.listIsNotEmpty((List) conditionValue)) {
                    updateWrapper.in(columnName, conditionValue); // list多个值使用in过滤条件
                }else if ( conditionValue != null && conditionValue.getClass().isArray() && Array.getLength(conditionValue) >0 ) {
                    updateWrapper.in(columnName, conditionValue); // 数组Array多个值使用in过滤条件
                } else if ( conditionValue instanceof String && "is not null".equals(conditionValue.toString())) {
                    updateWrapper.isNotNull(columnName);
                } else if ( conditionValue instanceof String && "is null".equals(conditionValue.toString())) {
                    updateWrapper.isNull(columnName);
                } else if ( conditionValue instanceof String && conditionValue.toString().indexOf(">") == 0) {
                    updateWrapper.gt(columnName, conditionValue.toString().substring(1));
                } else if ( conditionValue instanceof String && conditionValue.toString().indexOf("<") == 0) {
                    updateWrapper.lt(columnName, conditionValue.toString().substring(1));
                } else if ( conditionValue instanceof String && conditionValue.toString().indexOf(">=") == 0) {
                    updateWrapper.ge(columnName, conditionValue.toString().substring(2));
                } else if ( conditionValue instanceof String && conditionValue.toString().indexOf("<=") == 0) {
                    updateWrapper.le(columnName, conditionValue.toString().substring(2));
                } else{
                    updateWrapper.eq(columnName,conditionValue);
                }
            }
        }
        return batchCopyUpdate(updateWrapper,entityObj,null);
    }

    public  String getColumnNameByFieldName(Class clazz,String fieldName) {
        //动态获取表名对应的属性列名
        Field fieldOne = beanObjUtil.getFieldByName(clazz, fieldName);
        return getColumnNameByField(fieldOne);
    }
    public  String getColumnNameByField(Field fieldOne) {
        TableField tableFieldAnnotation = fieldOne.getAnnotation(TableField.class);
        String columnName = (tableFieldAnnotation != null && tableFieldAnnotation.value() != null)
                ? tableFieldAnnotation.value()
                : fieldOne.getName();
        return columnName;
    }
    /**
     * 获取所有的数据库列名
     * @param entityClass
     * @return
     */
    public  List<String> getColumnNames(Class<?> entityClass) {
        List<String> columnNames = new ArrayList<>();
        TableName tableNameAnnotation = entityClass.getAnnotation(TableName.class);
        String tableName = (tableNameAnnotation != null) ? tableNameAnnotation.value() : null;

        Field[] fields = entityClass.getDeclaredFields();
        for (Field field : fields) {
            TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
            if (tableFieldAnnotation != null && !tableFieldAnnotation.exist()) {
                continue; // 忽略不存在的字段
            }
            String columnName = (tableFieldAnnotation != null && tableFieldAnnotation.value() != null)
                    ? tableFieldAnnotation.value()
                    : field.getName();
            columnNames.add(columnName);
        }

        return columnNames;
    }
}
